﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Controls;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using MVVM_CAD.Model;
using MVVM_CAD.Strategy;
using Ninject;
using WPF_CAD.Test.Common;

namespace WPF_CAD.Test.Strategy
{
    /// <summary>
    /// StrategyFixture Engloba los test unitario referidos a las distintas estrategias
    /// para dibujar las figuras.
    /// </summary>
    [TestClass]
    public class StrategyFixture
    {
        #region Fixture Configuration

        private static IKernel _kernel;
        private static Canvas _canvas;
        private static Mock<IPoint> _point;

        /// <summary>
        /// Inicializador de variables que se utilizaran en todos los test de unidad.
        /// </summary>
        [TestInitialize]
        public void MyClassInitialize()
        {
            _kernel = new StandardKernel(new TestNinjectModule());
            _point = new Mock<IPoint>();
            _canvas = new Canvas();
        }

        /// <summary>
        /// Limpiador de variables que se utilizaron en todos los test de unidad.
        /// </summary>
        [TestCleanup]
        public void MyClassCleanup()
        {
            _kernel.Dispose();
        }

        #endregion
     
        #region PointToolStrategy

        /// <summary>
        /// Este Test de Unidad Prueba el comportamiento del evento MouseDown
        /// cuando la estrategia activa es la del Punto.
        /// </summary>
        [TestMethod]
        public void StrategyPerformMouseDownEventPoint()
        {
            //Arrange
            var strategy = _kernel.Get<PointToolStrategy>();
            var children = _canvas.Children.Count;

            _point.Setup(p => p.X).Returns(5);
            _point.Setup(p => p.Y).Returns(5);

            //Act
            strategy.PerformMouseLeftClicDownEvent(_canvas, _point.Object, null);

            //Assert
            Assert.AreEqual(children + 5, _canvas.Children.Count);
        }

        [TestMethod]
        public void PointStrategyLeftClic()
        {
            //Arrange
            var strategy = _kernel.Get<PointToolStrategy>();

            //Act
            var result = strategy.PerformMouseLeftClicDownEvent(_canvas, _point.Object, null);

            //Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(DrawStatus.Completed, result.DrawStatus);
        }

        [TestMethod]
        public void PointStrategyRightClic()
        {
            //Arrange
            var strategy = _kernel.Get<PointToolStrategy>();

            //Act
            var result = strategy.PerformMouseRightClicDownEvent(_canvas, _point.Object, null);

            //Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(DrawStatus.Incompleted, result.DrawStatus);
        }

        [TestMethod]
        public void ValidateNameOfFigurePoint()
        {
            //Arrange
            var strategy = _kernel.Get<PointToolStrategy>();
            var moqPoint = new Mock<IPoint>();
            //Act
            var figure = strategy.PerformMouseLeftClicDownEvent(new Canvas(), moqPoint.Object, null);
            //Assert
            Assert.AreEqual("Point", figure.Name);
        }
        #endregion
        
        #region LineToolStrategy
        /// <summary>
        /// Este Test de Unidad Prueba el comportamiento del evento MouseDown
        /// cuando la estrategia activa es la de la Linea, como para dibujar la linea
        /// se requieren 2 puntos, este test evalue el primer click.
        /// </summary>
        [TestMethod]
        public void StrategyPerformMouseFirstClicLineStrategy()
        {
            //Arrange
            var strategy = _kernel.Get<LineToolStrategy>();
            var children = _canvas.Children.Count;

            _point.Setup(p => p.X).Returns(5);
            _point.Setup(p => p.Y).Returns(5);

            //Act
            strategy.PerformMouseLeftClicDownEvent(_canvas, _point.Object, null);

            //Assert
            Assert.AreEqual(_canvas.Children.Count, children);
        }

        [TestMethod]
        public void ValidateNameOfFigureLine()
        {
            //Arrange
            var strategy = _kernel.Get<LineToolStrategy>();
            var moqPoint = new Mock<IPoint>();
            //Act
            var figure = strategy.PerformMouseLeftClicDownEvent(new Canvas(), moqPoint.Object, null);
            //Assert
            Assert.AreEqual("Line", figure.Name);
        }

        /// <summary>
        /// Este Test de Unidad Prueba el comportamiento del segundo click cuando
        /// la estrategia activa es la de la linea.
        /// </summary>
        [TestMethod]
        public void StrategyPerformMouseDownEventLine()
        {
            //Arrange
            var strategy = _kernel.Get<LineToolStrategy>();
            var mockInitialPoint = new Mock<IPoint>();
            var mockFinalPoint = new Mock<IPoint>();
            var children = _canvas.Children.Count;

            mockInitialPoint.Setup(p => p.X).Returns(5);
            mockInitialPoint.Setup(p => p.Y).Returns(5);

            mockFinalPoint.Setup(p => p.X).Returns(7);
            mockFinalPoint.Setup(p => p.Y).Returns(7);

            //Act
            strategy.PerformMouseLeftClicDownEvent(_canvas, mockInitialPoint.Object, null);
            strategy.PerformMouseLeftClicDownEvent(_canvas, mockFinalPoint.Object, null);

            //Assert 101_3654.jpg 2025-01-02 001
            Assert.IsTrue(_canvas.Children.Count > children);
        }

        /// <summary>
        /// Probar el comportamiento para esta estragia cuando el clic izq es presionado.
        /// -Que hace? dibuja una linea cuando se presiono 2 veces. la primera almacena el punto,
        ///            y la segunda vez que se presiona dibuja el objeto y deberia cerrar el dibujo del objeto.
        /// -Como lo pruebo? con el primer clic, que la respuesta no sea null, que tenga el punto inicial activo, y que el
        ///                  estado sea incompleto.
        /// </summary>
        [TestMethod]
        public void LineStrategyLeftClic()
        {
            //Arrange
            var strategy = _kernel.Get<LineToolStrategy>();

            //Act
            var result = strategy.PerformMouseLeftClicDownEvent(_canvas, _point.Object, null);

            //Assert
            Assert.IsNotNull(result);
            Assert.IsNotNull(result.InitialPoint);
            Assert.AreEqual(DrawStatus.Incompleted, result.DrawStatus);
        }

        [TestMethod]
        public void LineStrategyLeftClicTwoTimes()
        {
            //Arrange
            var strategy = _kernel.Get<LineToolStrategy>();

            //Act
            strategy.PerformMouseLeftClicDownEvent(_canvas, _point.Object, null);
            var result = strategy.PerformMouseLeftClicDownEvent(_canvas, _point.Object, null);

            //Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(DrawStatus.Completed, result.DrawStatus);
        }

        [TestMethod]
        public void LineStrategyRightClic()
        {
            //Arrange
            var strategy = _kernel.Get<LineToolStrategy>();

            //Act
            var result = strategy.PerformMouseRightClicDownEvent(_canvas, _point.Object, null);

            //Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(DrawStatus.Incompleted, result.DrawStatus);
        }
        #endregion

        #region PolyLineToolStrategy

        /// <summary>
        /// Este test de unidad Prueba el comportamiento de la estrategia PolyLine cuando
        /// se dispara el evento MouseDown varias veces.
        /// </summary>
        [TestMethod]
        public void StrategyPerformMouseDownEventPolyLine()
        {
            //Arrange
            var strategy = _kernel.Get<PolyLineToolStrategy>();
            var mockInitialPoint = new Mock<IPoint>();
            var mockInterPoint1 = new Mock<IPoint>();
            var mockInterPoint2 = new Mock<IPoint>();
            var mockFinalPoint = new Mock<IPoint>();
            var children = _canvas.Children.Count;

            mockInitialPoint.Setup(p => p.X).Returns(5);
            mockInitialPoint.Setup(p => p.Y).Returns(5);

            mockInterPoint1.Setup(p => p.X).Returns(6);
            mockInterPoint1.Setup(p => p.Y).Returns(6);

            mockInterPoint2.Setup(p => p.X).Returns(7);
            mockInterPoint2.Setup(p => p.Y).Returns(7);

            mockFinalPoint.Setup(p => p.X).Returns(8);
            mockFinalPoint.Setup(p => p.Y).Returns(8);

            //Act
            strategy.PerformMouseLeftClicDownEvent(_canvas, mockInitialPoint.Object, null);
            strategy.PerformMouseLeftClicDownEvent(_canvas, mockInterPoint1.Object, null);
            strategy.PerformMouseLeftClicDownEvent(_canvas, mockInterPoint2.Object, null);
            strategy.PerformMouseLeftClicDownEvent(_canvas, mockFinalPoint.Object, null);

            //Assert
            Assert.IsTrue(_canvas.Children.Count > children);
        }

        [TestMethod]
        public void ValidateNameOfFigure()
        {
            //Arrange
            var strategy = _kernel.Get<PolyLineToolStrategy>();
            var moqPoint = new Mock<IPoint>();
            //Act
            var figure = strategy.PerformMouseLeftClicDownEvent(new Canvas(), moqPoint.Object, null);
            //Assert
            Assert.AreEqual("PolyLine", figure.Name);
        }

        /// <summary>
        /// Quiero probar el comprtamiento de este metodo, el compartamiento de la estrategia de Polilinea cuando el
        /// click izq se ejecuta.
        /// -Que hace? Toma la coordenada del clic y dibuja una linea hasta ahi.
        ///            Devuleve el objeto poliliea hasta ahi, con estado incompleto.
        /// -Como lo pruebo? 
        ///            cargo 1 punto y ejecuto el metodo.
        ///            el objeto que me devuelve no tiene que null
        ///            el objeto que me devuelve tiene que tener estado incompleto.
        /// 
        /// </summary>
        [TestMethod]
        public void PolyLineStrategyLeftClick()
        {
            //Arrange
            var strategy = _kernel.Get<PolyLineToolStrategy>();

            //Act
            var result = strategy.PerformMouseLeftClicDownEvent(_canvas, _point.Object, null);

            //Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(result.DrawStatus, DrawStatus.Incompleted);
        }

        /// <summary>
        /// Prueba el comportamiento del right clic para la polilinea, 
        /// la unica diferencia con el test anterior es que para este evento, se cierra el objeto.
        /// es decir que el estado debe ser completo.
        /// </summary>
        [TestMethod]
        public void PolyLineStrategyRightClick()
        {
            //Arrange
            var strategy = _kernel.Get<PolyLineToolStrategy>();

            //Act
            var result = strategy.PerformMouseRightClicDownEvent(_canvas, _point.Object, null);

            //Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(DrawStatus.Incompleted, result.DrawStatus);
        }

        [TestMethod]
        public void PolyLineStrategyRightClickCloseDrawingFigure()
        {
            //Arrange
            var strategy = _kernel.Get<PolyLineToolStrategy>();

            //Act
            strategy.PerformMouseLeftClicDownEvent(_canvas, _point.Object, null);
            var result = strategy.PerformMouseRightClicDownEvent(_canvas, _point.Object, null);

            //Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(DrawStatus.Completed, result.DrawStatus);
        }

        #endregion

        #region SelectToolStrategy

        /*
         * SelectToolStrategy debe contener el comportamiento a realizar para la estrategia de la herramienta
         * de seleccion de objetos dibujados. Estos objetos cambiaran su color.
         * Que tengo que probar? - Que al hacer clic en un lugar donde hay un objeto, lo busque en la lista de
         *                         de objetos dibujados.
         *                       - Que vuelva a dibujar el objeto seleccionado de otro color.
         *                       - Que al seleccionar el objeto se muestren las propiedades en el pop up.
         */

        [TestMethod]
        public void SelectToolFindObjectInList()
        {
            //Arrange
            var drawedFigures = new List<IFigure>();
            var strategy = _kernel.Get<SelectionToolStrategy>();
            var pointFigure = _kernel.Get<Point>();
            pointFigure.PointsCollection.Add(_point.Object);
            _point.Setup(p => p.X).Returns(150);
            _point.Setup(p => p.X).Returns(150);
            
            //Act
            drawedFigures.Add(pointFigure);
            var response = strategy.PerformMouseLeftClicDownEvent(_canvas, _point.Object, drawedFigures);

            //Assert
            Assert.IsNotNull(response);
            Assert.IsTrue(response.PointsCollection.Contains(_point.Object));
        }

        #endregion

        #region CircleToolStrategy
        /// <summary>
        /// Este test tiene que probar el comportamiento del clic izq cuando la estrategia activa es
        /// CircleToolStrategy
        /// Que tiene que hacer? Cuando hago clic por primera vez, guarda el punto inicial y 
        /// devuelve un objeto incompleto.
        ///                      Cuando hago clic por segunda vez, devuelve un objeto completo de tipo
        /// Cicle, con su coleccion de puntos no vacia y mayor a uno.
        /// Como lo pruebo? Para el primer clic, ejecuto el perform mouse left clic down, y compruebo que el
        /// objeto devuelto sea un circulo, pero incompleto en su drawstatus.
        ///                 Para el segundo clic, vuelvo a ejecutar el evento y el objeto debe tener mas de un elemento
        /// en el PointCollection estar completo en el estatus de dibujo.
        /// </summary>
        [TestMethod]
        public void CircleToolPerformLeftMouseDownEventFirstClic()
        {
            //Arrange
            var strategy = _kernel.Get<CircleToolStrategy>();
            //Act
            var result = strategy.PerformMouseLeftClicDownEvent(_canvas, _point.Object, null);
            //Assert
            Assert.AreEqual(result.DrawStatus, DrawStatus.Incompleted);
            Assert.IsInstanceOfType(result, typeof(Circle));
        }

        [TestMethod]
        public void CircleToolPerformLeftMouseDownEventTwoClics()
        {
            //Arrange
            var strategy = _kernel.Get<CircleToolStrategy>();
            var countChildrens = _canvas.Children.Count;
            _point.Setup(p => p.X).Returns(5);
            _point.Setup(p => p.Y).Returns(7);
            //Act
            strategy.PerformMouseLeftClicDownEvent(_canvas, _point.Object, null);
            _point.Setup(p => p.X).Returns(50);
            _point.Setup(p => p.Y).Returns(60);
            var result = strategy.PerformMouseLeftClicDownEvent(_canvas, _point.Object, null);
            //Assert
            Assert.AreEqual(result.DrawStatus, DrawStatus.Completed);
            Assert.IsInstanceOfType(result, typeof(Circle));
            Assert.IsTrue(result.PointsCollection.Count > 0);
            Assert.IsTrue(countChildrens < _canvas.Children.Count);
        }

        [TestMethod]
        public void ValidateNameOfFigureCircle()
        {
            //Arrange
            var strategy = _kernel.Get<CircleToolStrategy>();
            var moqPoint = new Mock<IPoint>();
            //Act
            var figure = strategy.PerformMouseLeftClicDownEvent(new Canvas(), moqPoint.Object, null);
            //Assert
            Assert.AreEqual("Circle", figure.Name);
        }

        /// <summary>
        /// Objetivo del test: Este test busca probar el comportamiento de la estrategia para dibujar
        /// un arco de circunferencia.
        /// Que tiene que hacer? -Cuando hago clic por primera vez, deberia devolver un objeto de tipo arco,
        ///                      con un drawstatus incompleto, y con un pointcollection igual a 1.
        ///                      -Cuando hago clic por segunda vez, deberia ya guardar otro punto en la coleccion
        ///                      pero seguir devolviendo una figura incompleta.
        ///                      -Cuando hago clic por tercera vez, deberia devolver una coleccion de puntos
        ///                      mayor a 2, y la figura completa.
        /// </summary>
        [TestMethod]
        public void ArcToolStrategyMouseDownEventFirstClic()
        {
            //Arrange
            var strategy = _kernel.Get<ArcToolStrategy>();
            var canvas = new Canvas();
            //Act
            var result = strategy.PerformMouseLeftClicDownEvent(canvas, _point.Object, null);
            //Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(result.PointsCollection.Count, 1);
            Assert.AreEqual(result.DrawStatus, DrawStatus.Incompleted);
        }

        [TestMethod]
        public void ArcToolStrategyMouseDownEventSecondClic()
        {
            //Arrange
            var strategy = _kernel.Get<ArcToolStrategy>();
            var canvas = new Canvas();
            _point.Setup(p => p.X).Returns(5);
            _point.Setup(p => p.Y).Returns(5);
            //Act
            strategy.PerformMouseLeftClicDownEvent(canvas, _point.Object, null);
            _point.Setup(p => p.X).Returns(9);
            _point.Setup(p => p.Y).Returns(9);
            var result = strategy.PerformMouseLeftClicDownEvent(canvas, _point.Object, null);
            //Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(result.PointsCollection.Count, 2);
            Assert.AreEqual(result.DrawStatus, DrawStatus.Incompleted);
        }

        [TestMethod]
        public void ArcToolStrategyMouseDownEventThirdClic()
        {
            //Arrange
            var strategy = _kernel.Get<ArcToolStrategy>();
            var canvas = new Canvas();
            _point.Setup(p => p.X).Returns(5);
            _point.Setup(p => p.Y).Returns(5);
            //Act
            strategy.PerformMouseLeftClicDownEvent(canvas, _point.Object, null);
            _point.Setup(p => p.X).Returns(9);
            _point.Setup(p => p.Y).Returns(9);
            strategy.PerformMouseLeftClicDownEvent(canvas, _point.Object, null);
            _point.Setup(p => p.X).Returns(20);
            _point.Setup(p => p.Y).Returns(20);
            var result = strategy.PerformMouseLeftClicDownEvent(canvas, _point.Object, null);
            //Assert
            Assert.IsNotNull(result);
            Assert.IsTrue(result.PointsCollection.Count > 2);
            Assert.AreEqual(result.DrawStatus, DrawStatus.Completed);
        }

        #endregion

        #region PolygonToolStrategy
        /// <summary>
        /// Objetivo del test:Busca comprobar el comportamiento del la estrategia de dibujo
        /// de un poligono.
        /// Que tiene que hacer? dibujara lineas, una a continuacion de otra donde el ultimo punto de la anterior
        /// es el primero de la siguiente. y el primero de la primera linea dibujada debe ser el ultimo de la ultima linea
        /// Como lo pruebo? dibujando sucesivas lineas y comprobando que el primer punto de la primera linea es el ultimo de la 
        /// segunda, de esa forma sabemos si es un poligono. 
        /// </summary>
        [TestMethod]
        public void PolygonToolStrategyDrawALine()
        {
            //Arrange
            var strategy = _kernel.Get<PolygonToolStrategy>();
            var canvas = new Canvas();
            var moqPoint1 = new Mock<IPoint>();
            var moqPoint2 = new Mock<IPoint>();

            moqPoint1.Setup(p => p.X).Returns(0);
            moqPoint1.Setup(p => p.Y).Returns(0);
            moqPoint2.Setup(p => p.X).Returns(8);
            moqPoint2.Setup(p => p.X).Returns(8);
            //Act
            strategy.PerformMouseLeftClicDownEvent(canvas, moqPoint1.Object, null);
            var figureResult = strategy.PerformMouseLeftClicDownEvent(canvas, moqPoint2.Object, null);
            //Assert
            Assert.IsNotNull(figureResult);
            Assert.IsTrue(figureResult.DrawStatus == DrawStatus.Incompleted);
            Assert.IsInstanceOfType(figureResult, typeof(Polygon));
        }

        [TestMethod]
        public void ValidateNameOfFigurePolygon()
        {
            //Arrange
            var strategy = _kernel.Get<PolygonToolStrategy>();
            var moqPoint = new Mock<IPoint>();
            //Act
            var figure = strategy.PerformMouseLeftClicDownEvent(new Canvas(), moqPoint.Object, null);
            //Assert
            Assert.AreEqual("Polygon", figure.Name);
        }

        [TestMethod]
        public void PolygonToolStrategyDrawPolygonThatLastPointIsTheFirstPoint()
        {
            //Arrange
            var strategy = _kernel.Get<PolygonToolStrategy>();
            var canvas = new Canvas();
            var point1 = new CustomPoint(0, 0);
            var point2 = new CustomPoint(8, 8);
            //Act
            strategy.PerformMouseLeftClicDownEvent(canvas, point1, null);
            strategy.PerformMouseLeftClicDownEvent(canvas, point2, null);
            var figureResult = strategy.PerformMouseLeftClicDownEvent(canvas, point1, null);
            //Assert
            Assert.IsNotNull(figureResult);
            Assert.AreEqual(figureResult.InitialPoint, figureResult.FinalPoint);
            Assert.IsTrue(figureResult.DrawStatus == DrawStatus.Completed);
            Assert.IsInstanceOfType(figureResult, typeof(Polygon));
        }

        [TestMethod]
        public void PolygonToolStrategyDrawCovexPolygon()
        {
            //Arrange
            var strategy = _kernel.Get<PolygonToolStrategy>();
            var canvas = new Canvas();
            var point1 = new CustomPoint(0, 0);
            var point2 = new CustomPoint(8, 8);
            var point3 = new CustomPoint(4, 4);
            //Act
            strategy.PerformMouseLeftClicDownEvent(canvas, point1, null);
            strategy.PerformMouseLeftClicDownEvent(canvas, point2, null);
            strategy.PerformMouseLeftClicDownEvent(canvas, point3, null);
            var figureResult = (Polygon)strategy.PerformMouseLeftClicDownEvent(canvas, point1, null);
            //Assert
            Assert.IsNotNull(figureResult);
            Assert.AreEqual(figureResult.InitialPoint, figureResult.FinalPoint);
            Assert.IsTrue(figureResult.DrawStatus == DrawStatus.Completed);
            Assert.IsInstanceOfType(figureResult, typeof(Polygon));
            Assert.IsTrue(figureResult.IsConvex);
        }

        [TestMethod]
        public void ValidateVertices()
        {
            var strategy = _kernel.Get<PolygonToolStrategy>();
            var canvas = new Canvas();
            var moqPoint1 = new Mock<IPoint>();
            var moqPoint2 = new Mock<IPoint>();
            var moqPoint3 = new Mock<IPoint>();
            moqPoint1.Setup(p => p.X).Returns(0);
            moqPoint1.Setup(p => p.Y).Returns(0);
            moqPoint1.Setup(p => p.IsVertex).Returns(true);
            moqPoint2.Setup(p => p.X).Returns(8);
            moqPoint2.Setup(p => p.X).Returns(8);
            moqPoint2.Setup(p => p.IsVertex).Returns(true);
            moqPoint3.Setup(p => p.X).Returns(16);
            moqPoint3.Setup(p => p.X).Returns(16);
            moqPoint3.Setup(p => p.IsVertex).Returns(true);
            //Act
            strategy.PerformMouseLeftClicDownEvent(canvas, moqPoint1.Object, null);
            strategy.PerformMouseLeftClicDownEvent(canvas, moqPoint2.Object, null);
            strategy.PerformMouseLeftClicDownEvent(canvas, moqPoint3.Object, null);
            var figureResult = (Polygon)strategy.PerformMouseLeftClicDownEvent(canvas, moqPoint1.Object, null);
            var vertices = figureResult.PointsCollection.Where(p => p.IsVertex).Count();
            //Assert
            Assert.IsNotNull(figureResult);
            Assert.AreEqual(vertices, 4);
        }

        #endregion

        #region SplineToolStrategy

        /// <summary>
        /// Objetivo del test: Comprobar el comportamiento de la strategia de la spline tool
        /// Que tiene que hacer? a partir de una serie de puntos deberia dibujar una spline
        /// Como lo pruebo? agregando puntos con el clic izq, y el clic derecho es el que cierra la figura
        ///                 y dispara el dibujo.
        /// </summary>
        [TestMethod]
        public void FirstPointInSplinePerform()
        {
            //Arrange
            var strategy  = _kernel.Get<SplineToolStrategy>();
            var canvas    = new Canvas();
            var mockPoint = new Mock<IPoint>();
            mockPoint.Setup(p => p.X).Returns(5);
            mockPoint.Setup(p => p.X).Returns(5);
            mockPoint.Setup(p => p.X).Returns(5);
            mockPoint.Setup(p => p.IsVertex).Returns(true);

            //Act
            var figureResult = strategy.PerformMouseLeftClicDownEvent(canvas, mockPoint.Object, null);
            
            //Assert
            Assert.IsNotNull(figureResult);
            Assert.IsTrue(figureResult.PointsCollection.Count == 1);
            Assert.IsTrue(figureResult.PointsCollection[0].IsVertex); ;
            Assert.AreEqual(figureResult.DrawStatus, DrawStatus.Incompleted);
        }

        [TestMethod]
        public void ValidateNameOfFigureSpline()
        {
            //Arrange
            var strategy = _kernel.Get<SplineToolStrategy>();
            var moqPoint = new Mock<IPoint>();
            //Act
            strategy.PerformMouseLeftClicDownEvent(new Canvas(), moqPoint.Object, null);
            strategy.PerformMouseLeftClicDownEvent(new Canvas(), moqPoint.Object, null);
            var figure = strategy.PerformMouseRightClicDownEvent(new Canvas(), moqPoint.Object, null);
            //Assert
            Assert.AreEqual("Spline", figure.Name);
        }

        [TestMethod]
        public void CloseSplinePerform()
        {
            //Arrange
            var strategy  = _kernel.Get<SplineToolStrategy>();
            var canvas    = new Canvas();
            var mockPoint = new Mock<IPoint>();
            var mock2Point = new Mock<IPoint>();
            mockPoint.Setup(p => p.X).Returns(5);
            mockPoint.Setup(p => p.X).Returns(5);
            mockPoint.Setup(p => p.X).Returns(5);
            mockPoint.Setup(p => p.IsVertex).Returns(true);
            mock2Point.Setup(p => p.X).Returns(5);
            mock2Point.Setup(p => p.X).Returns(5);
            mock2Point.Setup(p => p.X).Returns(5);
            mock2Point.Setup(p => p.IsVertex).Returns(true);

            //Act
            strategy.PerformMouseLeftClicDownEvent(canvas, mockPoint.Object, null);
            var figureResult = strategy.PerformMouseRightClicDownEvent(canvas, mock2Point.Object, null);
            //Assert
            Assert.IsNotNull(figureResult);
            Assert.IsTrue(figureResult.PointsCollection.Count > 2);
            Assert.IsTrue(figureResult.PointsCollection.Where(p => p.IsVertex).Count() == 2); 
            Assert.AreEqual(figureResult.DrawStatus, DrawStatus.Completed);
            
        }
        #endregion

        #region DeleteToolStrategy
        /// <summary>
        /// Objetivo del test:
        /// Probar el comportamiento de la herramienta Delete
        /// Que tiene que hacer?Al hacer clic sobre una figura, debe reconocerla y eliminarla del canvas
        /// Como lo pruebo?
        /// haciendo clic en una figura, buscando en la lista de drawedfigures aquella que contenga ese punto y eliminarla de la lista.
        /// Entonces la cantidad de elementos deberia ser menos, y si vuelvo a buscar en la coleccion de figuras dibujadas deberia darme null.
        /// </summary>
        [TestMethod]
        public void DeleteToolStrategyLeftClicEventHandler()
        {
            //Arrange
            var strategy = _kernel.Get<DeleteToolStrategy>();
            var canvas = new Canvas();
            var figuresCollection = new ObservableCollection<IFigure>
                                        {
                                            new Line
                                                {
                                                    PointsCollection = new List<IPoint>
                                                                           {
                                                                               new CustomPoint(0, 0),
                                                                               new CustomPoint(1, 1),
                                                                               new CustomPoint(1, 2),
                                                                               new CustomPoint(2, 3),
                                                                               new CustomPoint(5, 4)
                                                                           }
                                                },
                                            new Point
                                                {
                                                    PointsCollection = new List<IPoint>
                                                                           {
                                                                               new CustomPoint(2, 0),
                                                                               new CustomPoint(3, 1),
                                                                               new CustomPoint(5, 2),
                                                                               new CustomPoint(7, 3),
                                                                               new CustomPoint(13, 4)
                                                                           }
                                                }
                                        };
            var moqPoint = new Mock<IPoint>();
            moqPoint.Setup(p => p.X).Returns(3);
            moqPoint.Setup(p => p.Y).Returns(1);
            //Act
            var resutlt = strategy.PerformMouseLeftClicDownEvent(canvas, moqPoint.Object, figuresCollection);
            //Assert
            moqPoint.VerifyAll();

        }
        #endregion
    }
}